<template>
  <div class="channel-edit">
    <van-cell :border="false">
      <div slot="title" class="title-text">我的频道</div>
      <!-- isEdit=!isEdit  取反实现切换效果 -->
      <van-button class="edit-btn" type="danger" round plain size="mini" @click="isEdit = !isEdit">{{ isEdit ? '完成' : '编辑' }}</van-button>
    </van-cell>
    <!-- gutter格子之间的间距 -->
    <van-grid class="my-grid" :gutter="10">
      <van-grid-item class="grid-item" v-for="(item, index) in myChannels" :key="index" @click="onMyChannelsClick(item, index)">
        <van-icon v-show="isEdit && !fixChannels.includes(item.id)" slot="icon" name="clear"></van-icon>
        <!--
          v-bind:class 语法
          里面一个对象，对象中的 key 表示要作用的 CSS 类名
          对象中的 value 要计算出布尔值
         true，则作用该类名
          false，不作用类名
         -->
        <span slot="text" :class="{ active: index === active }" class="text">{{
          item.name
        }}</span>
      </van-grid-item>
    </van-grid>

    <!-- 频道推荐 -->
    <van-cell :border="false">
      <div slot="title" class="title-text">频道推荐</div>
    </van-cell>
    <van-grid class="recommend-grid" :gutter="10">
      <van-grid-item class="grid-item" v-for="(item, index) in recommendChannels" :key="index" icon="plus" :text="item.name" @click="addChannels(item)" />
    </van-grid>
    <!-- /频道推荐 -->
  </div>
</template>

<script>
//接口方法导入时记得加大括号{}
import { getAllChannels,
addUserChannel, 
deleteUserChannel} from '@/api/channel.js'
import { login } from '@/api/user'
import {mapState} from 'vuex'
import {setItem} from '@/utils/storage.js'

export default {
  name: 'ChannelEdit',

  data() {
    return {
      // 全部频道列表数组
      allChannels: [],
      isEdit: false, //控制我的频道关闭按钮的显示与隐藏
      fixChannels: [0], //固定频道不允许删除
    }
  },
  props: {
    // 频道列表数组
    myChannels: {
      type: Array,
      required: true,
    },
    // 控制频道高亮
    active: {
      type: Number,
      required: true,
    },
  },
  mounted() {},
  computed: {
...mapState(['user']),//频道持久化所用


    // 定义计算属性 计算推荐频道列表
    // recommendChannels(){
    //   // 注意find 和forEach的用法   这个方法本质上还是双重循环
    //   const recomChannels=[]
    //   //遍历全部频道列表 去除其中的我的频道列表数据
    //  this.allChannels.forEach(Allitem =>{
    //   //find 遍历数组 找到满足条件的元素项
    //  const res= this.myChannels.find(myitem =>{
    //     return myitem.id===Allitem.id
    //   })
    //   // 如果我的频道中不包括该频道项，则收集到推荐频道中
    //   // console.log(res)
    //   if(!res){
    //     recomChannels.push(Allitem)
    //   }
    //  } )
    //   // 把计算结果返回
    //  return recomChannels
    // }

    // 计算属性会观测内部依赖数据的变化
    // 如果依赖的数据发生变化，则计算属性会重新执行
    //简化版
    recommendChannels() {
      // 数组的 filter 方法：遍历数组，把符合条件的元素存储到新数组中并返回
      return this.allChannels.filter((channel) => {
        // 数组的 find 方法：遍历数组，把符合条件的第1个元素返回
        // 当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素，之后的值不会再调用执行函数
        return !this.myChannels.find((myChannel) => {
          return myChannel.id === channel.id
        })
      })
    },
  },
  created() {
    this.loadAllChannels()
  },
  methods: {
    //获取全部频道列表
    async loadAllChannels() {
      try {
        const { data } = await getAllChannels()
        // console.log(data);
        const { channels } = data.data
        this.allChannels = channels
        // console.log(this.allChannels)
      } catch (err) {
        this.$toast('获取全部频道列表失败')
      }
    },
    // 添加频道
  async addChannels(channel) {
      // console.log(channel.name);
      this.myChannels.push(channel) //此处计算属性依赖的数据发生变化 会触发计算属性中的函数
      // 数据持久化处理
     if(this.user){
       try {
           // 已登录，把数据请求接口放到线上
   await addUserChannel({
    id:channel.id,//频道id
    seq:this.myChannels.length//序号
  })
       } catch (error) {
    this.$toast('保存失败，请稍后重试')
       }
     }else{
    // 未登录，把数据存储到本地(名称,数据)
     setItem('TOUTIAO_CHANNELS',this.myChannels)
     }
    },

    //我的频道列表的编辑与完成
    onMyChannelsClick(channel, index) {
      // console.log(channel,index);



      if (this.isEdit) {
         // 2.编辑状态 删除频道
        // 参数1：要删除的元素的开始索引（包括）
        // 参数2：删除的个数，如果不指定，则从参数1开始一直删除到最后
        //有一个问题:删除高亮频道的前面频道,高亮频道会变为原来高亮频道的后一个
        //原因:删除频道,active不会变化,但频道列表数组会变化,被删除频道的后面频道的索引都会减一
        //解决办法:删除一个元素,则让active减1   前提是删除的是高亮频道的前面频道
         //  1.如果是固定频道，则不删除
        if (this.fixChannels.includes(channel.id)) {
          return
        }

        if(this.active>=index){
          // 让激活频道的索引 - 1
          // 但因为active在props中,不能更新,所以还是传到父组件中
          // 子向父传值 用自定义事件
          //第一个参数 为自定义事件名
          // 第二个参数为要传的值
        this.$emit('update-active', this.active-1,true)
        }
          this.myChannels.splice(index, 1)

          //4.处理持久化删除频道  封装了一个方法
          this.deleteChannel(channel)
      } else {
        //3.非编辑状态 切换频道
        // 子组件使用this.$emit()向父组件传值

        this.$emit('update-active', index,false)
      }
    },
    //持久化删除频道
   async deleteChannel(channel){
    if(this.user){
      //已登录  更新到后台
      try {
        await deleteUserChannel(channel.id)
      } catch (error) {
        this.$toast('操作失败，请稍后重试')
      }
    }else{
      //未登录  更新到本地
       setItem('TOUTIAO_CHANNELS',this.myChannels)
    }
   }
  },
}
</script>

<style lang="less" scoped>
.channel-edit {
  padding: 85px 0;

  .title-text {
    font-size: 32px;
    color: #333333;
  }

  .edit-btn {
    width: 104px;
    height: 48px;
    font-size: 26px;
    color: #f85959;
    border: 1px solid #f85959;
  }
  :deep(.grid-item) {
    width: 160px;
    height: 86px;
    .van-grid-item__content {
      white-space: nowrap; //不让折行
      background-color: #f4f5f6;
      .van-grid-item__text,
      .text {
        font-size: 28px;
        color: #222;
        margin-top: 0;
      }
      .active {
        color: #f85959;
      }
      //给❌通过自定义插槽添加   vant组件给❌添加了一个父元素 即.van-grid-item__icon-wrapper
      //原先设置的相对定位的参照元素发生了变化 所以要将其父元素的position去掉
      .van-grid-item__icon-wrapper {
        position: unset;
      }
    }
  }
  :deep(.recommend-grid) {
    .grid-item {
      .van-grid-item__content {
        flex-direction: row;
        .van-icon-plus {
          font-size: 28px;
          margin-right: 6px;
        }
      }
    }
  }
  :deep(.my-grid ){
    .grid-item {
      .van-icon-clear {
        position: absolute;
        top: -10px;
        right: -10px;
        font-size: 30px;
        color: #cacaca;
        z-index: 2;
      }
    }
  }
}
</style>
